package common

import (
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
	systemReq "mycms/model/system/request"
	"reflect"
	"strings"
)

var Validate *validator.Validate
var trans ut.Translator

//	TODO 先固定中文，优化时可以通过 http 请求头的 'Accept-Language'获取
const locale = "zh"

// 初始化Validate/v10国际化
func init()  {
	zhT := zh.New() // 中文
	enT := en.New() // 英文
	uni := ut.New(enT, zhT)
	trans, _ = uni.GetTranslator(locale)

	Validate = validator.New()

	// 注册自定义的校验方法到 validator中
	_ = Validate.RegisterValidation("CheckMenuApi", systemReq.CheckMenuApi)
	_ = Validate.RegisterValidation("CheckMenuMethod", systemReq.CheckMenuMethod)

	//翻译器注册到validator
	switch locale {
		case "zh":
			_ = zhTranslations.RegisterDefaultTranslations(Validate, trans)
			//使用fld.Tag.Get("comment")注册一个获取tag的自定义方法
			//Validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
			//	return fld.Tag.Get("comment")
			//})
		case "en":
			_ = enTranslations.RegisterDefaultTranslations(Validate, trans)
			//Validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
			//	return fld.Tag.Get("en_comment")
			//})
	}

}

// 返回检验错误信息，优先返回errMsg标签内容，
func Translate(err error, obj interface{}) (errMsg string) {

	getObj := reflect.TypeOf(obj)

	if getObj.Kind() == reflect.Ptr {
		getObj = getObj.Elem()
	}
	if getObj.Kind() != reflect.Struct {
		//	obj不是结构体，直接返回错误信息
		return err.Error()
	}

	errs := err.(validator.ValidationErrors)
	for _, err := range errs {
		//	如果设置了errMsg标签，则返回errMsg内容，否则用翻译器翻译错误信息
		if f, exist := getObj.FieldByName(err.Field()); exist {
			errMsg = f.Tag.Get("errMsg")

			//	如果没有设置errMsg标签，直接返回错误信息
			if errMsg == "" {
				//	翻译错误信息
				errMsg = err.Translate(trans)

				if comment := f.Tag.Get("comment"); comment != "" {
					//	翻译后字段名还是英文，用comment标签的内容替换字段名
					errMsg = strings.Replace(errMsg, err.Field(), comment, 1)

				}

			}
		}

		if errMsg == "" {
			errMsg = err.Error()
		}
		break
	}
	return errMsg

}




